package com.chuanyun.wechatcheckin.service;

import com.chuanyun.wechatcheckin.config.WechatConfig;
import com.chuanyun.wechatcheckin.model.wechat.CheckinDayDataRequest;
import com.chuanyun.wechatcheckin.model.wechat.CheckinDayDataResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;

/**
 * 打卡日报数据服务类
 * 专门处理企业微信打卡日报数据相关的业务逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CheckinDayDataService {

    private final WechatConfig wechatConfig;
    private final WechatApiService wechatApiService;
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 获取打卡日报数据
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param userIdList 用户ID列表（可选，不超过100个）
     * @return 打卡日报数据响应
     * @throws Exception 异常
     */
    public CheckinDayDataResponse getCheckinDayData(LocalDate startDate, LocalDate endDate, 
                                                   List<String> userIdList) throws Exception {
        
        // 参数验证
        if (startDate == null || endDate == null) {
            throw new IllegalArgumentException("开始日期和结束日期不能为空");
        }
        
        if (startDate.isAfter(endDate)) {
            throw new IllegalArgumentException("开始日期不能晚于结束日期");
        }
        
        if (userIdList != null && userIdList.size() > 100) {
            throw new IllegalArgumentException("用户ID列表不能超过100个");
        }
        
        // 转换为Unix时间戳
        Long startTime = startDate.atStartOfDay().toEpochSecond(ZoneOffset.of("+8"));
        // endTime使用当前精确时间而不是日期0点
        Long endTime = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        
        // 构建请求参数
        CheckinDayDataRequest request = new CheckinDayDataRequest(startTime, endTime, userIdList);
        
        // 获取访问令牌
        String accessToken = wechatApiService.getCheckinAccessToken();
        
        // 构建请求URL
        String url = String.format("%s/cgi-bin/checkin/getcheckin_daydata?access_token=%s", 
                                 wechatConfig.getApi().getBaseUrl(), accessToken);
        
        // 发送HTTP请求
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            
            // 设置请求体
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
            
            // 记录请求信息（包含精确的时间戳）
            log.info("发送获取打卡日报数据请求: starttime={}, endtime={} (当前精确时间), 用户数: {}", 
                    startTime, endTime, userIdList != null ? userIdList.size() : "全部用户");
            
            log.info("发送获取打卡日报数据请求: {}", requestBody);
            
            return httpClient.execute(httpPost, response -> {
                String responseBody = EntityUtils.toString(response.getEntity());
                log.info("获取打卡日报数据响应: {}", responseBody);
                
                CheckinDayDataResponse checkinResponse = objectMapper.readValue(responseBody, CheckinDayDataResponse.class);
                
                if (!checkinResponse.isSuccess()) {
                    log.error("获取打卡日报数据失败: errcode={}, errmsg={}", 
                            checkinResponse.getErrCode(), checkinResponse.getErrMsg());
                    throw new RuntimeException("获取打卡日报数据失败: " + checkinResponse.getErrMsg());
                }
                
                return checkinResponse;
            });
        }
    }
    
    /**
     * 获取今天的打卡日报数据（endtime使用当前时间）
     */
    public CheckinDayDataResponse getTodayCheckinDayData(List<String> userIdList) throws Exception {
        LocalDate today = LocalDate.now();
        
        // 参数验证
        if (userIdList != null && userIdList.size() > 100) {
            throw new IllegalArgumentException("用户ID列表不能超过100个");
        }
        
        // 转换为Unix时间戳
        // startTime: 今天0点
        Long startTime = today.atStartOfDay().toEpochSecond(ZoneOffset.of("+8"));
        // endTime: 当前时间（包含时分秒）
        Long endTime = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        
        // 构建请求参数
        CheckinDayDataRequest request = new CheckinDayDataRequest(startTime, endTime, userIdList);
        
        // 获取访问令牌
        String accessToken = wechatApiService.getCheckinAccessToken();
        
        // 构建请求URL
        String url = String.format("%s/cgi-bin/checkin/getcheckin_daydata?access_token=%s", 
                                 wechatConfig.getApi().getBaseUrl(), accessToken);
        
        // 发送HTTP请求
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            
            // 设置请求体
            String requestBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
            
            log.info("发送获取今天打卡日报数据请求: {}", requestBody);
            
            return httpClient.execute(httpPost, response -> {
                String responseBody = EntityUtils.toString(response.getEntity());
                log.info("获取今天打卡日报数据响应: {}", responseBody);
                
                CheckinDayDataResponse checkinResponse = objectMapper.readValue(responseBody, CheckinDayDataResponse.class);
                
                if (!checkinResponse.isSuccess()) {
                    log.error("获取今天打卡日报数据失败: errcode={}, errmsg={}", 
                            checkinResponse.getErrCode(), checkinResponse.getErrMsg());
                    throw new RuntimeException("获取今天打卡日报数据失败: " + checkinResponse.getErrMsg());
                }
                
                return checkinResponse;
            });
        }
    }
    
    /**
     * 获取指定用户的打卡日报数据
     * @param userId 用户ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 打卡日报数据响应
     * @throws Exception 异常
     */
    public CheckinDayDataResponse getUserCheckinDayData(String userId, LocalDate startDate, 
                                                       LocalDate endDate) throws Exception {
        if (userId == null || userId.trim().isEmpty()) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        
        return getCheckinDayData(startDate, endDate, List.of(userId));
    }
    
    /**
     * 获取所有用户的打卡日报数据
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 打卡日报数据响应
     * @throws Exception 异常
     */
    public CheckinDayDataResponse getAllUsersCheckinDayData(LocalDate startDate, LocalDate endDate) throws Exception {
        return getCheckinDayData(startDate, endDate, null);
    }
    
    /**
     * 获取昨天的打卡日报数据
     * @param userIdList 用户ID列表（可选）
     * @return 打卡日报数据响应
     * @throws Exception 异常
     */
    public CheckinDayDataResponse getYesterdayCheckinDayData(List<String> userIdList) throws Exception {
        LocalDate yesterday = LocalDate.now().minusDays(1);
        return getCheckinDayData(yesterday, yesterday, userIdList);
    }
    
    /**
     * 获取指定用户昨天的打卡日报数据
     * @param userId 用户ID
     * @return 打卡日报数据响应
     * @throws Exception 异常
     */
    public CheckinDayDataResponse getUserYesterdayCheckinDayData(String userId) throws Exception {
        LocalDate yesterday = LocalDate.now().minusDays(1);
        return getUserCheckinDayData(userId, yesterday, yesterday);
    }
}